package com.stlm2.dems.service;

import com.stlm2.core.common.page.PageView;
import com.stlm2.dems.dao.*;
import com.stlm2.dems.entity.*;
import com.stlm2.dems.user.dao.AccountDao;
import com.stlm2.dems.user.entity.Account;
import com.stlm2.dems.user.entity.AccountState;
import com.stlm2.util.Convert;
import com.stlm2.util.codecontent.CodeContent;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;

import com.stlm2.core.base.BaseDao;
import com.stlm2.core.base.impl.BaseServiceImpl;
import org.springframework.ui.ModelMap;

import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service("refundLogService")
@Transactional(rollbackForClassName={"java.lang.Exception"}, propagation = Propagation.REQUIRED)
public class RefundLogService extends BaseServiceImpl<RefundLog> {

	@Resource
	private RefundLogDao refundLogDao;
	@Resource
	private ShopOrderDao shopOrderDao;
	@Resource
	private GoodsOrderDao goodsOrderDao;
	@Resource
	private UserDao userDao;
	@Resource
	private DdmShopDao ddmShopDao;
	@Resource
	private DdmGoodsDao ddmGoodsDao;
	@Resource
	private GoodSpecificationDao goodSpecificationDao;
	@Resource
	private ServiceOrderDao serviceOrderDao;
	@Resource
	private AccountDao accountDao;
	@Resource
	private FmsFlowDao fmsFlowDao;

	@Override
	protected BaseDao <RefundLog> getDao() {
		return refundLogDao;
	}


	/**
	 * 退款/售后申请
	 * ffl
	 * 2017-11-09 20:32:27
	 * @param token
	 * @param goodsOrderId
	 * @param refundTypeValue
	 * @param refundReasonValue
	 * @param refundMoney
	 * @param refundExplain
	 * @return
	 */
	public String refundApply(String token ,String goodsOrderId,String refundTypeValue,String refundReasonValue,String refundMoney,String refundExplain ,String picture){
		User user=userDao.getByToken(token);
		if (user==null){
			return CodeContent.getModelByCode(-1,"",null);
		}
		if (!NumberUtils.isDigits(goodsOrderId))
			return CodeContent.getModelByCode(0,"请指定要确认的订单",null);


		if (!NumberUtils.isDigits(refundTypeValue)){
			return CodeContent.getModelByCode(0,"服务类型不存在",null);

		}
		RefundType refundType = RefundType.getByIntValue(NumberUtils.toInt(refundTypeValue));
		if (refundType == null) {
			return CodeContent.getModelByCode(0,"服务类型不存在",null);
		}

		if (!NumberUtils.isDigits(refundReasonValue))
			return CodeContent.getModelByCode(0,"请选择退货原因",null);
		RefundReason refundReason = RefundReason.getByIntValue(NumberUtils.toInt(refundReasonValue));
		if (refundReason == null)
			return CodeContent.getModelByCode(0,"请选择退货原因",null);

		if (!NumberUtils.isNumber(refundMoney))
			return CodeContent.getModelByCode(0,"请填写退款金额",null);


		BigDecimal refundMoneyD=new BigDecimal(refundMoney);
		if (refundMoneyD.compareTo(new BigDecimal(0)) !=1 )
			return CodeContent.getModelByCode(0,"请输入有效的退款金额",null);


		GoodsOrder goodsOrder=goodsOrderDao.getById(NumberUtils.toInt(goodsOrderId));
		if (goodsOrder == null || goodsOrder.getShopOrderCode() == null ||( !OrderState.Receipt.equals(goodsOrder.getOrderState())&&!OrderState.Deliveried.equals(goodsOrder.getOrderState())))
			return CodeContent.getModelByCode(0,"订单退款退货失败",null);

		if(refundMoneyD.compareTo(goodsOrder.getPayMoney())==1)
			return CodeContent.getModelByCode(0,"退款金额不能大于"+goodsOrder.getPayMoney()+"",null);

		RefundLog refundLog = new RefundLog();
		String code = CodeContent.gCode("R", user.getId());
		refundLog.setCode(code);
		refundLog.setReferCode(goodsOrder.getShopOrderCode());
		refundLog.setRefundType(refundType);
		refundLog.setRefundState(RefundState.Apply);
		refundLog.setRefundReason(refundReason);
		refundLog.setGoodsOrderId(goodsOrder.getId());
		refundLog.setTotalMoney(refundMoneyD);
		refundLog.setNum(goodsOrder.getNum());
		if (!StringUtils.isBlank(refundExplain)){
			if (refundExplain.length() > 300)
				return CodeContent.getModelByCode(0,"退款说明长度不能大于300",null);

			refundLog.setRefundExplain(refundExplain);
		}
		refundLog.setUserId(goodsOrder.getUserId());
		refundLog.setCreateTime(new Date());
		if(!com.stlm2.util.StringUtils.isNullOrEmpty(picture)){
			refundLog.setPicture(picture);
		}
		ShopOrder shopOrder = shopOrderDao.getByCode(goodsOrder.getShopOrderCode());
		if (shopOrder == null)
			return CodeContent.getModelByCode(0,"退款失败",null);
		refundLog.setShopOrderId(shopOrder.getId());
		//修改三级订单
		goodsOrder.setOrderState(OrderState.RefundApply);
		goodsOrderDao.modify(goodsOrder);
		//添加退款单
		refundLogDao.add(refundLog);
		//参与售后的单子 用户不可评价此单商品
		Boolean hasComment=shopOrder.getHasComment()!=null?shopOrder.getHasComment():true;
		if(hasComment){
			shopOrder.setHasComment(false);
			shopOrderDao.modify(shopOrder);
			goodsOrderDao.updateComment(shopOrder.getCode());
		}

		return CodeContent.getModelByCode(1,"",null);
	}


	/**
	 * 用户取消退款/售后 申请
	 * ffl
	 * 2017-11-10 16:44:23
	 * @param token
	 * @param refundId
	 * @return
	 */
	public String refundShutDown(String token,String refundId){
		User user=userDao.getByToken(token);
		if (user==null){
			return CodeContent.getModelByCode(-1,"",null);
		}
		if (!NumberUtils.isDigits(refundId)){
			return CodeContent.getModelByCode(0,"未传入退款记录id",null);
		}
		RefundLog refundLog=refundLogDao.getById(NumberUtils.toInt(refundId));
		if(refundLog==null){
			return CodeContent.getModelByCode(0,"未找到退款记录",null);
		}
		if(user.getId()-refundLog.getUserId()!=0){
			return CodeContent.getModelByCode(0,"该记录不是您的退款申请记录",null);
		}

		GoodsOrder goodsOrder=goodsOrderDao.getById(refundLog.getGoodsOrderId());
		if(goodsOrder==null){
			return CodeContent.getModelByCode(0,"未找到订单信息",null);
		}
		ShopOrder shopOrder=shopOrderDao.getById(refundLog.getShopOrderId());
		if(shopOrder==null){
			return CodeContent.getModelByCode(0,"未找到订单信息",null);
		}
		if(RefundState.Apply.equals(refundLog.getRefundState())){
			refundLog.setRefundState(RefundState.Shutdown);
			refundLog.setHandleTime(new Date());
			refundLog.setHandleUserId(user.getId());
			goodsOrder.setOrderState(shopOrder.getOrderState());
			refundLogDao.modify(refundLog);
			goodsOrderDao.modify(goodsOrder);
		}else {
			if (!RefundState.Shutdown.equals(refundLog.getRefundState())) {
				return CodeContent.getModelByCode(0,"非退款申请状态不能关闭",null);
			}
		}
		return  CodeContent.getModelByCode(1,"",null);
	}


	/**
	 * 退款/售后 list
	 * ffl
	 * 2017-11-12 15:31:20
	 * @param token
	 * @param userName
	 * @param cnName
	 * @param code
	 * @param referCode
	 * @param refundStateValue
	 * @param pageNum
	 * @return
	 */
	public String search(String token,String userName,String cnName,String code ,String referCode,String refundStateValue,String pageNum){
		User user=userDao.getByToken(token);
		if (user==null){
			return CodeContent.getModelByCode(-1,"",null);
		}
		int pageNo=1;
		if(NumberUtils.isDigits(pageNum)){
			pageNo=NumberUtils.toInt(pageNum);
		}else {
			return CodeContent.getModelByCode(0,"未传入查看页数",null);
		}
		RefundLog refundLog=new RefundLog();
		if (!com.stlm2.util.StringUtils.isNullOrEmpty(userName)){
			refundLog.setUserName(userName);
		}
		if (!com.stlm2.util.StringUtils.isNullOrEmpty(cnName)){
			refundLog.setCnName(cnName);
		}
		if (!com.stlm2.util.StringUtils.isNullOrEmpty(code)){
			refundLog.setCode(code);
		}
		if (!com.stlm2.util.StringUtils.isNullOrEmpty(referCode)){
			refundLog.setReferCode(referCode);
		}
		if(NumberUtils.isDigits(refundStateValue)){
			refundLog.setRefundStateValue(NumberUtils.toInt(refundStateValue));
		}
		PageView pageView=refundLogDao.queryPageView(pageNo,10,refundLog);
		ModelMap model = new ModelMap();
		if (pageView != null) {
			model.put("refundList", convertRefundLog(pageView.getRecords()));
			model.put("recordsTotal",pageView.getRowCount());
			model.put("totalPage", pageView.getPageCount());
		}
		model.put("pageNo", pageNo);
		return CodeContent.getModelByCode(1,"",model);
	}

	public List<ModelMap> convertRefundLog(List<RefundLog> refundLogList) {
		List<ModelMap> list = new ArrayList<ModelMap>();
		if ( refundLogList != null &&  refundLogList.size() > 0) {
			for (RefundLog refundLog :  refundLogList) {
				ModelMap map = buildModelRefundLog(refundLog);
				list.add(map);
			}
		}

		return list;
	}
	public ModelMap buildModelRefundLog(RefundLog refundLog) {
		ModelMap model = new ModelMap();
		if (refundLog!= null) {
			model.put("id", refundLog.getId());
			model.put("code", refundLog.getCode());
			model.put("referCode",refundLog.getReferCode());
			model.put("refundState", refundLog.getRefundState() != null ?refundLog.getRefundState().toString() : "");
			model.put("refundStateValue", refundLog.getRefundStateValue());
			model.put("refundType", refundLog.getRefundType() != null ?refundLog.getRefundType().toString() : "");
			model.put("refundTypeValue", refundLog.getRefundTypeValue());
			model.put("refundReason", refundLog.getRefundReason() != null ?refundLog.getRefundReason().toString() : "");
			model.put("refundReasonValue", refundLog.getRefundReasonValue());
			model.put("goodsOrderId",refundLog.getGoodsOrderId());
			GoodsOrder goodsOrder=goodsOrderDao.getById(refundLog.getGoodsOrderId());
			ShopOrder shopOrder =shopOrderDao.getById(refundLog.getShopOrderId());
			String shopName="叮当网";
			String goodsName="";
			String goodsImg="";
			String specificationName="";
			if(shopOrder!=null){
				DdmShop shop =ddmShopDao.getById(shopOrder.getShopId());
				if(shop!=null){
					shopName=shop.getName();
				}
			}
			String goodsOrderCode="";
			int goodsNum=0;
			BigDecimal payMoney=null;
			if(goodsOrder!=null){
				goodsOrderCode=goodsOrder.getCode();
				DdmGoods goods=ddmGoodsDao.getById(goodsOrder.getGoodsId());
				if(goods!=null){
					goodsName=goods.getName();
					goodsImg=goods.getMainImg();
				}
                goodsNum=goodsOrder.getNum();
				payMoney=goodsOrder.getPayMoney()!=null?goodsOrder.getPayMoney():new BigDecimal(0);
				if(goodsOrder.getGoodsSpecificationId()!=null){
					GoodSpecification goodSpecification=goodSpecificationDao.getById(goodsOrder.getGoodsSpecificationId());
					if(goodSpecification!=null){
						specificationName=goodSpecification.getPropertiesName();
					}
				}
			}
			model.put("payMoney",payMoney);
			model.put("goodsNum",goodsNum);
			String userName="";
			String realName="";
			User user=userDao.getById(refundLog.getUserId());
			if (user!=null){
				userName=user.getName();
				realName=user.getRealName();
			}
			model.put("userName",userName);
			model.put("realName",realName);
			model.put("goodsOrderCode",goodsOrderCode);
			model.put("goodsImg",goodsImg);
			model.put("goodsName",goodsName);
			model.put("specificationName",specificationName);
			model.put("shopName",shopName);
			model.put("num",refundLog.getNum());
			model.put("refundMoney",refundLog.getTotalMoney());
			model.put("createTime", Convert.toFullYMDHMS(refundLog.getCreateTime()));
			model.put("handleTime", refundLog.getHandleTime()!=null?Convert.toFullYMDHMS(refundLog.getHandleTime()):"");
			String handleName="";
			if(refundLog.getHandleUserId()!=null) {
				User handleUser = userDao.getById(refundLog.getHandleUserId());
				if (handleUser != null) {
					handleName=handleUser.getRealName();
				}
			}
			model.put("handleName",handleName);
            model.put("picture",refundLog.getPicture()!=null?refundLog.getPicture():"");
		}
		return model;
	}

	/**
	 * 获取记录详情
	 * ffl
	 * 2017-11-12 16:09:16
	 * @param token
	 * @param id
	 * @return
	 */
	public String getByIdForDetail(String token,String id){
		User user=userDao.getByToken(token);
		if(user==null){
			return CodeContent.getModelByCode(-1,"",null);
		}
		if(!NumberUtils.isDigits(id)){
			return CodeContent.getModelByCode(0,"未传要查看的退款售后记录id",null);
		}
		RefundLog refundLog=refundLogDao.getById(NumberUtils.toInt(id));
		return CodeContent.getModelByCode(1,"",buildModelRefundLog(refundLog));
	}


	/**
	 * 处理退款/售后
	 * ffl
	 * 2017-11-13 09:27:40
	 * @param token
	 * @param id
	 * @param handleValue 2不同意  3同意
	 * @param refundMoney
	 * @param num
	 * @return
	 */
	public String handleRefundLog(String token,String id,String handleValue,String refundMoney,String num){
		User user=userDao.getByToken(token);
		if(user==null){
			return CodeContent.getModelByCode(-1,"",null);
		}
		if(!NumberUtils.isDigits(id)){
			return CodeContent.getModelByCode(0,"未传入退款售后记录id",null);
		}
		RefundLog refundLog=refundLogDao.getById(NumberUtils.toInt(id));
		if (refundLog==null){
			return CodeContent.getModelByCode(0,"未找到退款售后记录",null);
		}
		if (!RefundState.Apply.equals(refundLog.getRefundState())){
			return CodeContent.getModelByCode(0,"退款售后记录不是申请状态",null);
		}
		if (!NumberUtils.isDigits(handleValue))
			return CodeContent.getModelByCode(0,"请选择订单的处理类型",null);


		RefundState refundState=RefundState.getByIntValue(NumberUtils.toInt(handleValue));
		if (refundState == null)
			return CodeContent.getModelByCode(0,"请选择订单的处理类型",null);

		refundLog.setHandleTime(new Date());
		refundLog.setHandleUserId(user.getId());
		refundLog.setRefundState(refundState);

		Account account=accountDao.getByUserId(refundLog.getUserId());
		if(account==null){
			CodeContent.getModelByCode(0,"未找到该用户资金账号",null);
		}
		GoodsOrder goodsOrder=goodsOrderDao.getById(refundLog.getGoodsOrderId());
		if (goodsOrder==null){
			return CodeContent.getModelByCode(0,"未找到商品订单信息",null);
		}


		if(refundState.equals(RefundState.Refuse)){//拒绝
			goodsOrder.setOrderState(OrderState.Receipt);
			refundLogDao.modify(refundLog);
			goodsOrderDao.modify(goodsOrder);
            //短信通知等 预留

		}else if (refundState.equals(RefundState.Success)){//同意

			if(!NumberUtils.isNumber(refundMoney)){
				return CodeContent.getModelByCode(0,"未传入退款金额",null);
			}
			BigDecimal money=new BigDecimal(refundMoney);
			if(money.compareTo(goodsOrder.getPayMoney())==1){
				return CodeContent.getModelByCode(0,"退款金额不能大于购买金额:"+goodsOrder.getPayMoney(),null);
			}
			if(money.compareTo(refundLog.getTotalMoney())==1){
				return CodeContent.getModelByCode(0,"退款金额不能大于退款申请金额:"+goodsOrder.getPayMoney(),null);
			}
			if(!NumberUtils.isDigits(num)){
				return CodeContent.getModelByCode(0,"未传入商品个数",null);
			}
            if(NumberUtils.toInt(num)>goodsOrder.getNum()){
				return CodeContent.getModelByCode(0,"申请商品个数不能大于商品订单购买个数:"+goodsOrder.getNum(),null);
			}
			refundLog.setNum(NumberUtils.toInt(num));
			refundLog.setTotalMoney(money);
			goodsOrder.setOrderState(OrderState.Refund);
			refundLogDao.modify(refundLog);
			goodsOrderDao.modify(goodsOrder);
			if(!AccountState.Normal.equals(account.getAccountState())){
				CodeContent.getModelByCode(0,"该用户资金账号已被锁定",null);
			}
			account.setAccountMoney(account.getAccountMoney().add(money));
			FmsFlow fmsFlow=new FmsFlow();
			fmsFlow.setUserId(refundLog.getUserId());
			fmsFlow.setType(FlowType.Add);
			fmsFlow.setSource(FlowSource.BuyRefund);
			fmsFlow.setReferCode(goodsOrder.getCode());
			fmsFlow.setCreateTime(new Date());
			fmsFlow.setChange_num(money);
			fmsFlowDao.add(fmsFlow);
			accountDao.modify(account);
			//取消增值服务
			serviceOrderDao.updateState(goodsOrder.getCode());

			//短信通知等 预留


		}else {
			return CodeContent.getModelByCode(0,"无权限关闭退款申请",null);
		}


		return CodeContent.getModelByCode(1,"",buildModelRefundLog(refundLog));
	}

}